#define GPA0CON 		( *((volatile unsigned long *)0xE0200000) )		
#define GPA1CON 		( *((volatile unsigned long *)0xE0200020) )

// UART registers
#define ULCON0 			( *((volatile unsigned long *)0xE2900000) )		
#define UCON0 			( *((volatile unsigned long *)0xE2900004) )
#define UFCON0 			( *((volatile unsigned long *)0xE2900008) )
#define UMCON0 			( *((volatile unsigned long *)0xE290000C) )
#define UTRSTAT0 		( *((volatile unsigned long *)0xE2900010) )
#define UERSTAT0 		( *((volatile unsigned long *)0xE2900014) )
#define UFSTAT0 		( *((volatile unsigned long *)0xE2900018) )
#define UMSTAT0 		( *((volatile unsigned long *)0xE290001C) )
#define UTXH0 			( *((volatile unsigned long *)0xE2900020) )
#define URXH0 			( *((volatile unsigned long *)0xE2900024) )
#define UBRDIV0 		( *((volatile unsigned long *)0xE2900028) )
#define UDIVSLOT0 		( *((volatile unsigned long *)0xE290002C) )
#define UINTP 			( *((volatile unsigned long *)0xE2900030) )
#define UINTSP 			( *((volatile unsigned long *)0xE2900034) )
#define UINTM 			( *((volatile unsigned long *)0xE2900038) )

#define UART_UBRDIV_VAL		35
#define UART_UDIVSLOT_VAL	0x1

// init uart
void uart_init()
{
	// 1 Configurae GPIO as RX/TX
	GPA0CON = 0x22222222;
	GPA1CON = 0x2222;

	// 2 Set data format
	// Enable fifo
	UFCON0 = 0x1;
	// no flow control
	UMCON0 = 0x0;
	// Data:8, no ECC, stop: 1
	ULCON0 = 0x3;
	// clock:PCLK，don't use interrupt enable UART send/recv
	UCON0  = 0x5;  				

	// 3 Set band rate
	UBRDIV0 = UART_UBRDIV_VAL;
	UDIVSLOT0 = UART_UDIVSLOT_VAL;
}

// recv a char
char getc(void)
{
	// If RX FIFO is null wait it.
	while (!(UTRSTAT0 & (1<<0)));
	// Get data
	return URXH0;                   	
}

// Send a char
void putc(char c)
{
	// If Tx FIFO is full, wait.
	while (!(UTRSTAT0 & (1<<2)));
	// write data
	UTXH0 = c;                      	
}

/*
 * Print Hex data
 * Ex：int a = 0x68; puthex(a); print "68";
 */
int puthex(volatile unsigned char a)
{
    volatile unsigned char cTmp;

    //putchar(a);
    //
    //printf("\n%x\n", a);

    //Method 2，calc
    cTmp=a>>4; 
    if(cTmp<10) {
		cTmp+='0';
	} else {
		cTmp+='A'-10;  
    }
    putc(cTmp);
    cTmp=a&0x0f;
    if(cTmp<10)
    {
        cTmp+='0';
    }
    else
    {
        cTmp+='A'-10;
    }
    putc(cTmp);

    return 0;
}

int put32bits(volatile unsigned int a)
{
	unsigned char c = 0;
	int i = 0;
	for ( i=3; i>=0; i-- )
	{
		c = ( (a>>(8*i)) & 0xff );
		puthex(c);
	}

	return 0;
}
void putint_hex(int a)
{
	puthex( (a>>24) & 0xFF );
	puthex( (a>>16) & 0xFF );
	puthex( (a>>8) & 0xFF );
	puthex( (a>>0) & 0xFF );
}
void dump_hex(unsigned long *p, int len){
	int j = 0, i = 0;
	for (j = 0; j < len; j++)
	{	
		putint_hex(p);putc(':');
		for (i = 0; i < 4; i++) {
			putint_hex(*p++);	
			putc(':');
		}
		putc('\n');putc('\r');
	}
}
